package com.ehotting.mqbd.core.manager;

import com.ehotting.mqbd.api.bean.nacos.NacosContentBean;
import com.ehotting.mqbd.api.bean.nacos.NacosMqbdBean;
import com.ehotting.mqbd.api.bean.solver.ModuleSolverBean;
import com.ehotting.mqbd.api.bean.solver.SolverInfoBean;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.dataformat.yaml.YAMLFactory;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import com.ehotting.eaf.spring.cloud.service.NacosConfigService;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

@Component
public class NacosSolverManager {

    private static final Logger logger = LoggerFactory.getLogger(NacosSolverManager.class);

    @Autowired
    private NacosConfigService nacosConfigService;

    private final String PRE_NAME = "mqbd-solverInfo";

    private ObjectMapper objectMapper = new ObjectMapper(new YAMLFactory());

    public void add(String module, SolverInfoBean solverInfo) throws JsonProcessingException {
        logger.info("Start add.");
        logger.info("module:{},solverInfo:{}",module,solverInfo);
        NacosContentBean mqbd = getNacosSolver();

        add(module, solverInfo, mqbd.getMqbd().getSolver());
        save(mqbd);
        logger.info("Finish add.");
    }

    public void delete(String module, SolverInfoBean serverInfo) throws JsonProcessingException {
        NacosContentBean solver = getNacosSolver();
        delete(module, serverInfo, solver.getMqbd().getSolver());
        save(solver);
    }

    private NacosContentBean getNacosSolver() throws JsonProcessingException {
        String content = nacosConfigService.get(PRE_NAME);
        NacosContentBean nacosContent = objectMapper.readValue(content, NacosContentBean.class);
        if(nacosContent == null || nacosContent.getMqbd()==null){
            logger.info("mqbd or mqbd.getMqbd() is null.");
            nacosContent = createNacosSolver();
        }
        return nacosContent;
    }

    private NacosContentBean createNacosSolver(){
        NacosContentBean  nacosContent = new NacosContentBean();
        nacosContent.setMqbd(new NacosMqbdBean());
        nacosContent.getMqbd().setSolver(new ModuleSolverBean());
        return nacosContent;
    }


    private void save(NacosContentBean solver) throws JsonProcessingException {
        logger.info("Start save.");
        String yamlString = objectMapper.writeValueAsString(solver);
        yamlString = yamlString.replace("\"","").replace("'","").replace("---", "");
        logger.info("yamlString:{}.",yamlString);
        nacosConfigService.save(PRE_NAME, yamlString);
        logger.info("Finish save.");
    }

    private void add(String module, SolverInfoBean solverInfo, ModuleSolverBean moduleSolver){
        if(!moduleSolver.containsKey(module)){
            logger.info("create ArrayList");
            moduleSolver.put(module,new ArrayList<>());
        }

        if(moduleSolver.containsKey(module)){
            Object  list  = moduleSolver.get(module);
            if(list == null || !(list instanceof ArrayList)){
                logger.info("list is null Or !(list instanceof ArrayList)");
                moduleSolver.put(module,new ArrayList<>());
            }
        }


        if(!moduleSolver.get(module).contains(solverInfo)){
            logger.info("add solverInfo in moduleSolver");
            moduleSolver.get(module).add(solverInfo);
        }
    }

    private void delete(String module, SolverInfoBean serverInfo, ModuleSolverBean moduleSolver){
        List<SolverInfoBean> delList = new ArrayList<>();
        if(moduleSolver.containsKey(module)){
            delList = moduleSolver.get(module).stream().filter(t->{
                return t.equals(serverInfo);
            }).collect(Collectors.toList());
        }
        if(moduleSolver.containsKey(module)) {
            moduleSolver.get(module).removeAll(delList);
        }
    }
}
